import Card from "@/components/Card";
import CardBox from "@/components/CardBox";

import domCreate from "@/utils/DomCreate"

export default {
    components: {
        Card,
        CardBox
    },
    data(){
        return {
            /**
             * 纸牌数据集合(剩余未使用牌)
             */
            cardDataList: [],
            /**
             * 纸牌列表
             */
            cardList: {},
            /**
             * 纸牌动画间隔时间
             */
            cardAnimationDuration: 200,
            /**
             * 纸牌池列表
             */
            cardPoolList: {},
            /**
             * 纸牌池位置
             */
            cardPoolPosition: {
                top: 10,
                left: 10
            },
            /**
             * 纸牌El对象集合
             */
            cardElList: {},
            /**
             * 移动中的纸牌id集合
             */
            colCardIds: [],
            /**
             * 移动中的纸牌el对象集合
             */
            colCardEls: [],
            /**
             * 牌盒列表
             */
            cardBoxList: {},
            /**
             * 记录纸牌 (用于撤销)
             * {
             *    containerId: 牌原所属容器id
             *    cardIds: 移动的纸牌id集合
             *    openCardId: 翻开的纸牌id
             * }
             */
            cardHistoryList: []
        }
    },
    methods:{
        /**
         * 生成纸牌数据
         */
        generateCardData(){
            //8副牌
            for (let i = 0; i < 8; i++) {

                //一副牌13张
                for (let j = 0; j < 13; j++) {

                    let type = 3;
                    switch (this.gameGrade){
                        //初级
                        case 0:
                            //单色 - 黑桃
                            type = 3;
                            break;
                        //中级
                        case 1:
                            //双色 - 红桃和黑桃
                            type = (i % 2) + 2;
                            break;
                        //高级
                        case 2:
                            //四色
                            type = i % 4;
                            break;
                    }

                    let cardData = {type ,num: j + 1};
                    this.cardDataList.push(cardData);
                }
            }
            //乱序 -- 将牌打乱
            this.cardDataList.sort(() => { return Math.random() > 0.5 ? -1 : 1 })

        },
        /**
         * 获取一张指派数据
         */
        getOneCard(){
            let cardData = {...this.cardDataList[0]};
            this.cardDataList.splice(0, 1);
            return cardData;
        },
        createCard(cardNum = 54, timeout = 1000){
            let cardInfoList = []
            for (let i = 0; i < cardNum; i++) {
                let id = this.generateId();
                let value = this.getOneCard();
                let status = cardNum - i <= this.containerNum ? 1 : 0;
                let prop = {id, value: { ...value, status }, cardMousedown: this.cardMousedown, cardMouseup: this.cardMouseup};
                cardInfoList.push(prop);
            }
            this.delayExecute(() => {
                //发牌
                this.licensing(cardInfoList, 50);
            }, timeout);
        },
        /**
         * 创建牌池
         */
        createCardPool(num = 6){
            let {left, top} = this.cardPoolPosition;
            for (let i = 0; i < num; i++) {
                let id = this.generateId();
                let position = {left: left + 20 * i, top };
                let prop = {id, value:{status:2}, position , cardClick: this.cardClick };
                domCreate(Card, prop, { id });
                this.cardPoolList[id] = prop;
            }
        },
        /**
         * 创建牌盒
         */
        createCardBox(num = 8){

            let space = 10;
            let cellW = this.winWidth / (num + 2);
            let containerTop = 10;
            for (let i = num; i > 0; i--) {
                let position = {
                    top: containerTop,
                    left: cellW * (i + 1) + space,
                    width: cellW - space * 2,
                    height: 150
                };
                let id = this.generateId();
                let props = {id, position, cardIds: []};
                this.cardBoxList[id] = {...props};
                domCreate(CardBox, props, { id });
            }
        },
        /**
         * 获取未使用的纸牌盒id
         */
        getNotUsedCardBoxId(){
            let keys = Object.keys(this.cardBoxList);
            let result = null;
            for (let i = 0; i < keys.length; i++) {
                let cardBox = this.cardBoxList[keys[i]];
                if(!cardBox.use){
                    result = keys[i];
                    break;
                }
            }
            return result;
        },
        /**
         * 获取最后一个牌池id
         */
        getLastCardPoolId(){
            let cardPoolKeys = Object.keys(this.cardPoolList);
            let cardPoolSize = cardPoolKeys.length;
            let lastCardPoolId = null;
            if(cardPoolSize > 0){
                lastCardPoolId = cardPoolKeys[cardPoolSize - 1];
            }
            return lastCardPoolId;
        },
        /**
         * 获取一列牌
         * @param cardId
         */
        getColCardIds(cardId){
            let card = this.cardList[cardId];
            let index = this.findCardInContainerIndex(card.containerId, cardId);
            let container = this.containerList[card.containerId];
            let cardIds = container.cardIds;

            let result = []
            for (let i = index; i < cardIds.length; i++) {
                result.push(cardIds[i]);
            }

            return result;

        },
        /**
         * 移动牌
         */
        moveCard(cardId, targetLeft, targetTop){
            let cardEl = this.getElement(cardId);
            cardEl.style.transition = `${this.cardAnimationDuration}ms`;
            cardEl.style.left = `${targetLeft}px`;
            cardEl.style.top = `${targetTop}px`;
            this.delayExecute(() => {
                cardEl.style.transition = `0s`;
            }, this.cardAnimationDuration)
        },
        /**
         * 发牌 (包括创建牌元素)
         * @param cardInfoList 牌信息列表
         * @param intervalTime 发牌间隔时间
         */
        licensing(cardInfoList, intervalTime = 100){
            let containerKeys = Object.keys(this.containerList);
            let containerSize = containerKeys.length;
            let lastCardPoolId = this.getLastCardPoolId();
            let lastCardPoolEl = this.getElement(lastCardPoolId);

            let position = {
                top: lastCardPoolEl && lastCardPoolEl.offsetTop || this.cardPoolPosition.top,
                left: lastCardPoolEl && lastCardPoolEl.offsetLeft || 50
            }

            for (let i = 0; i < cardInfoList.length; i++) {
                this.delayExecute(() => {
                    let cardInfo = {...cardInfoList[i], position};
                    let cardId = cardInfo.id;
                    this.cardList[cardId] = {...cardInfo};
                    let cardEl = domCreate(Card, cardInfo, { id: cardId });
                    this.cardElList[cardId] = cardEl;
                    cardEl.$el.style.transition = `${this.cardAnimationDuration}ms`;
                    // cardEl.$el.style.left = `0px`;
                    // cardEl.$el.style.top = `0px`;
                    let containerIndex = i % containerSize;
                    this.delayExecute(() => {

                        this.receivingCard(Object.keys(this.containerList)[containerIndex], [cardId], true);

                        //发到最后一张牌，把牌池销毁,为了页面效果好看，加10毫秒延时
                        this.delayExecute(() => {
                            if(i === cardInfoList.length - 1 && lastCardPoolEl){
                                delete this.cardPoolList[lastCardPoolId]
                                lastCardPoolEl.remove();
                            }
                        }, 10, true)
                    },10)
                }, intervalTime * i, () => {
                    cardEl && cardEl.$el && cardEl.$el.remove();
                });
            }
        },
        /**
         * 纸牌按下事件
         * @param cardId 纸牌id
         * @param than 纸牌this对象
         * @param e 纸牌div对象
         */
        cardMousedown(cardId, than, e){

            if(!this.checkCanMove(cardId)){
                return false;
            }

            this.colCardIds = this.getColCardIds(cardId);

            this.colCardEls = [];
            for (let i = 0; i < this.colCardIds.length; i++) {
                this.colCardEls.push(this.getElement(this.colCardIds[i]));
            }

            let cardEl = this.colCardEls[0];

            this.cardMove(cardEl.offsetLeft, cardEl.offsetTop, true);
            // cardEl.style.zIndex = 9999;
            //算出鼠标相对元素的位置
            let disX = e.clientX - cardEl.offsetLeft;
            let disY = e.clientY - cardEl.offsetTop;

            let left = '';
            let top = '';
            document.onmousemove = (e)=>{
                //用鼠标的位置减去鼠标相对元素的位置，得到元素的位置
                left = e.clientX - disX;
                top = e.clientY - disY;
                //网页可见宽
                let docWidth = document.body.clientWidth;
                //网页可见高
                let docHeight = document.body.clientHeight;
                //超下边界(键盘DIV长宽分别为 295px、210px)
                if(top > docHeight - cardEl.clientHeight){
                    top = docHeight - cardEl.clientHeight
                }
                //超上边界
                if(top < 0) {
                    top = 0
                }
                //超右边界
                if(left > docWidth - cardEl.clientWidth){
                    left = docWidth - cardEl.clientWidth
                }
                if(left < 0){//超左边界
                    left = 0
                }
                //绑定元素位置到positionX和positionY上面
                //移动当前元素
                cardEl.style.left = `${left}px`;
                cardEl.style.top = `${top}px`;

                this.cardMove(left, top);

            };
            document.onmouseup = (e) => {
                document.onmousemove = null;
                document.onmouseup = null;

                for (let i = 0; i < this.colCardEls.length; i++) {
                    let colCardEl = this.colCardEls[i];
                    colCardEl.style.zIndex = 2;
                }
            };
        },
        /**
         * 卡移动函数
         * @param left 首张牌的 left 坐标
         * @param top 首张牌的 top 坐标
         * @param isReady 是否为准备移动(鼠标按下为true)
         */
        cardMove(left, top, isReady = false){
            for (let i = 0; i < this.colCardEls.length; i++) {
                let colCardEl = this.colCardEls[i];
                if(isReady){
                    colCardEl.style.transition = `${100}ms`;
                }
                colCardEl.style.zIndex = 99;
                colCardEl.style.left = `${ left }px`;
                colCardEl.style.top = `${top + 30 * i}px`;
                if(isReady){
                    this.delayExecute(() => {

                        colCardEl.style.transition = `0s`;
                    }, 100)
                }
            }
        },
        /**
         * 纸牌松开事件
         * @param cardId 纸牌id
         * @param than 纸牌this对象
         * @param e 纸牌div对象
         */
        cardMouseup(cardId, than, e) {

            if(than && ((than && than.value.status) !== 1 || this.colCardIds.length === 0)){
                return;
            }

            if(!!this.currentContainer){
                //在区域内

                if(!this.receivingCard(this.currentContainer.id, this.colCardIds)){
                    //接收牌不成功，则回去原容器
                    let card = this.cardList[cardId];
                    if(card && card.containerId){
                        //回去原容器
                        this.receivingCard(card.containerId, this.colCardIds)
                    }
                }
            }else{
                // 在容器区域外
                let card = this.cardList[cardId];
                if(card && card.containerId){
                    //回去原容器
                    this.receivingCard(card.containerId, this.colCardIds)
                }
            }

            this.getElement(cardId).style.zIndex = 2;

            this.colCardIds = [];
        },
        /**
         * 牌池点击
         * @param cardId
         * @param than
         * @param e
         */
        cardClick(cardId, than, e){
            //是否能发牌
            let flag = true;
            let containerIds = Object.keys(this.containerList);
            for (let i = 0; i < containerIds.length; i++) {
                let containerId = containerIds[i];
                let container = this.containerList[containerId];
                let cardIds = container.cardIds;
                if(!(cardIds && cardIds.length > 0)){
                    //存在空列，禁止发牌
                    flag = false;
                    break;
                }
            }

            if(flag){
                this.clearHistory();
                this.createCard(10, 10)
                this.showToast("正在发牌")
            } else {
                this.showToast("玩牌区各列必须至少有一张牌才能发牌。" , 1500)

            }
        },
        /**
         * 检查是否可以移动
         * @param cardId
         */
        checkCanMove(cardId){

            let card = this.cardList[cardId];
            //如果纸牌不是翻开状态的，则不允许移动返回false
            if(card.value.status !== 1){
                return false;
            }
            let flag = false;

            if(card.containerId){
                let container = this.containerList[card.containerId];
                let cardIds = container.cardIds;
                //前一张牌
                let priorCard = undefined;
                for (let i = 0; i < cardIds.length; i++) {
                    let cardIdTemp = cardIds[i];

                    if(cardIdTemp === cardId){
                        //最后一张图,则允许
                        if(cardIds.length - 1 === i){
                            return true;
                        } else {
                            priorCard = this.cardList[cardId];
                        }

                    }else if(priorCard !== undefined){
                        let thisCard = this.cardList[cardIdTemp]
                        if(thisCard.value.num + 1 === priorCard.value.num && thisCard.value.type === priorCard.value.type){
                            //直到最后一张图,则允许
                            if(cardIds.length - 1 === i){
                                return true;
                            }else{
                                priorCard = thisCard;
                            }
                        }else{
                            return false;
                        }
                    }
                }
            }

            return flag;
        }
    }
}